Completed
Push — master ( 0a8aee...45be8d )
by Andres
30s
created

angular.controller(ꞌct_fusionꞌ)   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
nc 1
dl 0
loc 5
rs 9.4285
nop 1
1
/**
2
 fusion
3
 Component that handles the fusion of isotopes to create new ones.
4
5
 @namespace Components
6
 */
7
'use strict';
8
9
angular.module('game').component('fusion', {
10
  templateUrl: 'views/fusion.html',
11
  controller:  'ct_fusion',
12
  controllerAs: 'ct'
13
});
14
15
angular.module('game').controller('ct_fusion', ['state', 'format', 'visibility', 'data', 'util', 'reaction',
16
  function (state, format, visibility, data, util, reactionService) {
17
    let ct = this;
18
    ct.state = state;
19
    ct.data = data;
20
    ct.util = util;
21
    ct.format = format;
22
    ct.adjustAmount = [1, 10, 25, 100];
23
24
    function getFermiRadius(resource) {
25
      let isotope = data.resources[resource];
26
      let A = isotope.energy/data.constants.U_TO_EV;
27
      return data.constants.FERMI_RADIUS * Math.pow(A, 0.3333);
28
    }
29
30
    function getZ(resource){
31
      let isotope = data.resources[resource];
32
      let element = Object.keys(isotope.elements)[0];
33
      return data.elements[element].number;
34
    }
35
36
    ct.getCapacity = function(resource, player) {
37
      let isotope = data.resources[resource];
38
      let element = Object.keys(isotope.elements)[0];
39
      let r = data.elements[element].van_der_waals;
40
      let area = Math.PI*r*r;
41
      return util.calculateValue(data.global_upgrades.fusion_area.power.base,
42
            data.global_upgrades.fusion_area.power,
43
            player.global_upgrades_current.fusion_area)/area;
44
    };
45
46
    ct.getTime = function(player) {
47
      let time = ct.getFusionReaction(player).reactant.eV/util.calculateValue(data.global_upgrades.fusion_bandwidth.power.base,
48
            data.global_upgrades.fusion_bandwidth.power,
49
            player.global_upgrades.fusion_bandwidth);
50
      time = Math.floor(time);
51
      return Math.max(1, time);
52
    };
53
54
    ct.getProductIsotope = function(beam, target) {
55
      let beamN = parseInt(beam, 10);
56
      let targetN = parseInt(target, 10);
57
58
      let beamZ = getZ(beam);
59
      let targetZ = getZ(target);
60
61
      let productN = beamN+targetN;
62
      let productZ = beamZ+targetZ;
63
64
      return data.resource_matrix[productZ][productN];
65
    };
66
67
    ct.getProductEnergy = function(beam, target) {
68
      let product = ct.getProductIsotope(beam, target);
69
      if(!product){
70
        return 0;
71
      }
72
      let beamBE = data.resources[beam].binding_energy;
73
      let targetBE = data.resources[target].binding_energy;
74
      let productBE = data.resources[product].binding_energy;
75
76
      return productBE - (beamBE + targetBE);
77
    };
78
79
    ct.getCoulombBarrier = function(beam, target) {
80
      let beamZ = getZ(beam);
81
      let beamR = getFermiRadius(beam);
82
83
      let targetZ = getZ(target);
84
      let targetR = getFermiRadius(target);
85
86
      let coulombBarrier = data.constants.COULOMB_CONSTANT*beamZ*targetZ*
87
              Math.pow(data.constants.ELECTRON_CHARGE, 2)/(beamR+targetR);
88
      return coulombBarrier * data.constants.JOULE_TO_EV;
89
    };
90
91
    ct.getYieldPercent = function(player) {
92
      let beam = state.player.fusion[0].beam;
93
      let target = state.player.fusion[0].target;
94
      let beamR = getFermiRadius(beam.name);
95
      let targetR = getFermiRadius(target.name);
96
      let beamArea = Math.PI*beamR*beamR;
97
      let targetArea = Math.PI*targetR*targetR;
98
99
      let reactorArea = util.calculateValue(data.global_upgrades.fusion_area.power.base,
100
            data.global_upgrades.fusion_area.power,
101
            player.global_upgrades_current.fusion_area);
102
      let beamPercentArea = beamArea*beam.number/reactorArea;
103
      let targetPercentArea = targetArea*target.number/reactorArea;
104
105
      return beamPercentArea*targetPercentArea;
106
    };
107
108
    ct.getYield = function(player){
109
      let percentYield = ct.getYieldPercent(player);
110
      let target = state.player.fusion[0].target.number;
111
      let beam = state.player.fusion[0].beam.number;
112
      // the yield comes from wherever source is more abundant
113
      let impacted = Math.max(target, beam);
114
      return Math.floor(percentYield*impacted);
115
    };
116
117
    ct.getFusionReaction = function(player) {
118
      let reaction = {
119
        reactant: {},
120
        product: {}
121
      };
122
123
      let beam = state.player.fusion[0].beam;
124
      let target = state.player.fusion[0].target;
125
126
      reaction.reactant[beam.name] = beam.number;
127
      reaction.reactant[target.name] = target.number;
128
129
      let coulombBarrier = ct.getCoulombBarrier(beam.name, target.name);
130
      reaction.reactant.eV = coulombBarrier*beam.number;
131
132
      let product = ct.getProductIsotope(beam.name, target.name);
133
      let numberYield = ct.getYield(player);
134
135
      reaction.product[product] = numberYield;
136
137
      // return the leftovers from the reaction
138
      if(numberYield < beam.number){
139
        reaction.product[beam.name] = beam.number - numberYield;
140
      }
141
      if(numberYield < target.number){
142
        reaction.product[target.name] = target.number - numberYield;
143
      }
144
145
      let energyExchange = ct.getProductEnergy(beam.name, target.name);
146
      if(energyExchange < 0){
147
        reaction.reactant.eV += energyExchange*numberYield;
148
      }else if(energyExchange > 0){
149
        reaction.product.eV = energyExchange*numberYield;
150
      }
151
152
      return reaction;
153
    };
154
155
    function activateFusion(player){
156
      let beam = player.fusion[0].beam;
157
      let target = player.fusion[0].target;
158
159
      if(player.resources[beam.name].number < beam.number ||
160
        player.resources[target.name].number < target.number){
161
        player.fusion[0].running = false;
162
        return;
163
      }
164
      player.resources[beam.name].number -= beam.number;
165
      player.resources[target.name].number -= target.number;
166
167
      player.fusion[0].running = true;
168
    }
169
170
    ct.stopFusion = function(player, fusion) {
171
      if(fusion.running){
172
        let beam = state.player.fusion[0].beam;
173
        let target = state.player.fusion[0].target;
174
175
        player.resources[beam.name].number += fusion.beam.number;
176
        player.resources[target.name].number += fusion.target.number;
177
      }
178
179
      fusion.eV = 0;
180
      fusion.active = false;
181
      fusion.running = false;
182
      fusion.run = false;
183
    };
184
185
    function updateFusion(player, fusion) {
186
        let bandwidth = util.calculateValue(data.global_upgrades.fusion_bandwidth.power.base,
187
            data.global_upgrades.fusion_bandwidth.power,
188
            player.global_upgrades.fusion_bandwidth);
189
        let spent = Math.min(player.resources.eV.number, bandwidth);
190
        fusion.eV += spent;
191
        player.resources.eV.number -= spent;
192
    }
193
194
    function endFusion(player, fusion, reaction) {
195
      // energy is not lost! if there are leftovers, give them back to the player
196
      let leftover = fusion.eV - reaction.reactant.eV;
197
      reaction.product.eV = reaction.product.eV + leftover || leftover;
198
      // Reaction checks that the player has the quantity necessary
199
      // to react, but here eV is stored in the fusion object. By setting the cost to 0
200
      // we make sure that it always work
201
      reaction.reactant= {eV:0};
202
      reactionService.react(1, reaction, player);
203
204
      fusion.eV = 0;
205
      player.fusion[0].running = false;
206
    }
207
208
    function update(player){
209
      for(let fusion of player.fusion){
210
        if(!fusion.active){
211
          continue;
212
        }
213
        if(fusion.eV === 0 && fusion.run){
214
          activateFusion(player);
215
        }
216
        if(!fusion.running){
217
          continue;
218
        }
219
        updateFusion(player, fusion);
220
        let reaction = ct.getFusionReaction(player);
221
        if(fusion.eV >= reaction.reactant.eV){
222
          endFusion(player, fusion, reaction);
223
        }
224
      }
225
    }
226
227
    ct.adjustLevel = function(player, upgrade, amount){
228
      player.global_upgrades_current[upgrade] += amount;
229
      // We cap it between 1 and the current max level
230
      player.global_upgrades_current[upgrade] = Math.max(1, Math.min(player.global_upgrades_current[upgrade], player.global_upgrades[upgrade]));
231
    };
232
233
    state.registerUpdate('fusion', update);
234
  }
235
]);
236